/*
    Dart中抽象类:Dart抽象类主要用于定义标准，子类可以继承抽象类，也可以实现抽象类接口。
      1、抽象类通过abstract关键字来定义
      2、Dart中的抽象方法不能用abstract声明，Dart中没有方法体的方法我们称为抽象方法。
      3、如果子类继承抽象类必须得实现里面的抽象方法
      4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。
      5、抽象类不能被实例化，只有继承它的子类可以

    extends抽象类和implements的区别:
      1、如果要复用抽象类里面的方法，并且要用抽象方法约束子类的话我们就用extends继承抽象类
      2、如果只是把抽象类当做标准的话我们就用implements实现抽象类
*/

// 案例：定义一个Animal类，要求他的子类必须包含eat方法
abstract class Animal {
  eat(); //抽象方法，没有函数体，未来的子类必须要实现这个方法
  run();

  // 当然，抽象类里面也可以有非抽象方法
  void printInfo(){
    print('我是Animal类中的一个非抽象方法');
  }
}

// 使用implements关键字来实现抽象类
class Dog extends Animal {
  @override
  eat() {
    print('小狗在吃翔');
    return null;
  }

  @override
  run() {
    print('小狗在奔跑');
  }
}

class Cat extends Animal {
  @override
  eat() {
    print('小猫在吃鱼');
  }

  @override
  run() { 
    print('小猫在奔跑');
  }
}

void main() {
  // var animal = new Animal();//爆红，因为抽象类不能直接被实例化

  var dog = new Dog();
  dog.eat();
  dog.printInfo();//子类的实例当然可以调用到父类身上的方法

  var cat = new Cat();
  cat.eat();
  cat.printInfo();//子类的实例当然可以调用到父类身上的方法
}
